
`include "common_header.verilog"

//  *************************************************************************
//  File : top_dec10b8b.v
//  *************************************************************************
//  This program is controlled by a written license agreement.
//  Unauthorized Reproduction or Use is Expressly Prohibited. 
//  Copyright (c) 2002-2003 MoreThanIP, Germany
//  Designed by : Sebastien Marcellier
//  info@morethanip.com
//  *************************************************************************
//  Decription : Decoder (Transmission code 8b/10b)
//  Version    : $Id: top_dec10b8b.v,v 1.9 2011/03/29 10:37:16 mr Exp $
//  *************************************************************************

module top_dec10b8b (

   rst_align,
   din,
   ce,
   dout,
   kout,
   char_err,
   disp_err,
   sync,
   comma,
   clk,
  `ifdef USE_CLK_ENA
   clk_ena,
  `endif   
   enable_cgalign,
   rst);

input   rst_align;      //  Reset Alignment 
input   [19:0] din;     //  parallel byte of incoming data  	
input   ce;             //  asserted when input data are stable        
output  [15:0] dout;    //  parallel output data        
output  [1:0] kout;     //  special caracter detected        
output  [1:0] char_err; //  flag asserted when the data in detected faulty                
output  [1:0] disp_err; //  flag asserted when a disparity error is detected
output  sync;           //  asserted when synchronisation detected        
output  comma;          //  comma detect        
input   clk;            //  main clock    
`ifdef USE_CLK_ENA
input   clk_ena;        //  Enable clk
`endif
input   enable_cgalign; //  code group alignment
input   rst;            //  asynchronous reset

wire    [15:0] dout1; 
reg     [15:0] dout; 
wire    [1:0] kout1; 
reg     [1:0] kout; 
wire    [1:0] char_err1;
reg     [1:0] char_err;
wire    [1:0] disp_err1; 
reg     [1:0] disp_err; 
reg     sync; 
wire    comma1; 
reg     comma;   
wire    disp_0; 
reg     disp_reg;
wire    disp_1;
wire    [19:0] din_int;
wire    sync_int;
wire    sync_dec;

assign sync_dec = 1'b 1;        // decoders should work permanently

align_sync20b U_ALIGN (

        .rst_align(rst_align),
        .din(din),
        .dout(din_int),
        .sync(sync_int),
        .comma(comma1),
        .ce(ce),
        .clk(clk),
       `ifdef USE_CLK_ENA
        .clk_ena(clk_ena),
       `endif        
        .enable_cgalign(enable_cgalign),
        .rst(rst));

dec_func_xgxs U_DEC1 (

        .din(din_int[19:10]),
        .sync(sync_dec),
        .ce(ce),
        .dout(dout1[15:8]),
        .kout(kout1[1]),
        .rd_in(disp_0),
        .rd_out(disp_1),
        .char_err(char_err1[1]),
        .disp_err(disp_err1[1]),
        .clk(clk),
       `ifdef USE_CLK_ENA
        .clk_ena(clk_ena),
       `endif         
        .rst(rst));
        
dec_func_xgxs U_DEC0 (

        .din(din_int[9:0]),
        .sync(sync_dec),
        .ce(ce),
        .dout(dout1[7:0]),
        .kout(kout1[0]),
        .rd_in(disp_reg),
        .rd_out(disp_0),
        .char_err(char_err1[0]),
        .disp_err(disp_err1[0]),
        .clk(clk),
       `ifdef USE_CLK_ENA
        .clk_ena(clk_ena),
       `endif         
        .rst(rst));


`ifdef MTIPXGXS_DPREGS

always @(posedge rst or posedge clk)
   begin : process_1
   if (rst == 1'b 1)
      begin
      dout[15:8] <= 8'h00;      
      kout[1]    <= 1'b 0;  
      dout[7:0]  <= 8'h00;      
      kout[0]    <= 1'b 0;  
      char_err    <= 2'b 00;      
      disp_err    <= 2'b 00;  
      comma       <= 1'b 0;  
      end
   else
      begin
        
         `ifdef USE_CLK_ENA
            if(clk_ena == 1'b 1)
            begin
         `endif          
        
                if(char_err1[0] == 1'b 1 | disp_err1[0] == 1'b 1)
                   begin
                   dout[7:0]  <= 8'hFE;
                   kout[0]    <= 1'b 1;
                   end
                else
                   begin
                   dout[7:0]  <= dout1[7:0];
                   kout[0]    <= kout1[0];
                   end           

                if(char_err1[1] == 1'b 1 | disp_err1[1] == 1'b 1)
                   begin
                   dout[15:8] <= 8'hFE;      
                   kout[1]    <= 1'b 1;  
                   end
                else
                   begin
                   dout[15:8] <= dout1[15:8];
                   kout[1]    <= kout1[1];  
                   end           
        
                char_err    <= char_err1;      
                disp_err    <= disp_err1;
                comma       <= comma1;  

         `ifdef USE_CLK_ENA
            end
         `endif
        
        end
   end

`else
        // unregistered
        
        always @(char_err1 or disp_err1 or dout1 or kout1)
        begin
        
                if(char_err1[0] == 1'b 1 | disp_err1[0] == 1'b 1)
                   begin
                   dout[7:0]  = 8'hFE;
                   kout[0]    = 1'b 1;
                   end
                else
                   begin
                   dout[7:0]  = dout1[7:0];
                   kout[0]    = kout1[0];
                   end           
        
                if(char_err1[1] == 1'b 1 | disp_err1[1] == 1'b 1)
                   begin
                   dout[15:8] = 8'hFE;      
                   kout[1]    = 1'b 1;  
                   end
                else
                   begin
                   dout[15:8] = dout1[15:8];
                   kout[1]    = kout1[1];  
                   end           
        
        end

        always @( char_err1 )
        begin
                char_err = char_err1;
        end
        
        always @( disp_err1 )
        begin
                disp_err = disp_err1;
        end

        always @( comma1 )
        begin
                comma = comma1;
        end


`endif


always @(posedge rst or posedge clk)
   begin : process_4
   if (rst == 1'b 1)
      begin
      disp_reg <= 1'b 0; 
      sync     <= 1'b0; 
      end
   else
      begin
      
         `ifdef USE_CLK_ENA
            if(clk_ena == 1'b 1)
            begin
         `endif       
      
              disp_reg <= disp_1;   
              sync     <= sync_int;
      
         `ifdef USE_CLK_ENA
            end
         `endif       
      
      end
   end

endmodule